home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / include / glibmm-2.4 / glibmm / arrayhandle.h next >
Encoding:
C/C++ Source or Header  |  2006-04-20  |  14.3 KB  |  523 lines

  1. // -*- c++ -*-
  2. #ifndef _GLIBMM_ARRAYHANDLE_H
  3. #define _GLIBMM_ARRAYHANDLE_H
  4.  
  5. /* $Id: arrayhandle.h,v 1.3 2003/04/21 17:39:41 murrayc Exp $ */
  6.  
  7. /* Copyright (C) 2002 The gtkmm Development Team
  8.  *
  9.  * This library is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU Library General Public
  11.  * License as published by the Free Software Foundation; either
  12.  * version 2 of the License, or (at your option) any later version.
  13.  *
  14.  * This library is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17.  * Library General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU Library General Public
  20.  * License along with this library; if not, write to the Free
  21.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include <glibmm/containerhandle_shared.h>
  25.  
  26.  
  27. namespace Glib
  28. {
  29.  
  30. namespace Container_Helpers
  31. {
  32.  
  33. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  34.  
  35. /* Count the number of elements in a 0-terminated sequence.
  36.  */
  37. template <class T> inline
  38. size_t compute_array_size(const T* array)
  39. {
  40.   const T* pend = array;
  41.  
  42.   while(*pend)
  43.     ++pend;
  44.  
  45.   return (pend - array);
  46. }
  47.  
  48. /* Allocate and fill a 0-terminated array.  The size argument
  49.  * specifies the number of elements in the input sequence.
  50.  */
  51. template <class For, class Tr>
  52. typename Tr::CType* create_array(For pbegin, size_t size, Tr)
  53. {
  54.   typedef typename Tr::CType CType;
  55.  
  56.   CType *const array = static_cast<CType*>(g_malloc((size + 1) * sizeof(CType)));
  57.   CType *const array_end = array + size;
  58.  
  59.   for(CType* pdest = array; pdest != array_end; ++pdest)
  60.   {
  61.     // Use & to force a warning if the iterator returns a temporary object.
  62.     *pdest = Tr::to_c_type(*&*pbegin);
  63.     ++pbegin;
  64.   }
  65.  
  66.   *array_end = CType();
  67.   return array;
  68. }
  69.  
  70.  
  71. /* Convert from any container that supports forward
  72.  * iterators and has a size() method.
  73.  */
  74. template <class Tr, class Cont>
  75. struct ArraySourceTraits
  76. {
  77.   typedef typename Tr::CType CType;
  78.  
  79.   static size_t get_size(const Cont& cont)
  80.     { return cont.size(); }
  81.  
  82.   static const CType* get_data(const Cont& cont, size_t size)
  83.     { return Glib::Container_Helpers::create_array(cont.begin(), size, Tr()); }
  84.  
  85.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_SHALLOW;
  86. };
  87.  
  88. /* Convert from a 0-terminated array.  The Cont argument must be a pointer
  89.  * to the first element.  Note that only arrays of the C type are supported.
  90.  */
  91. template <class Tr, class Cont>
  92. struct ArraySourceTraits<Tr,Cont*>
  93. {
  94.   typedef typename Tr::CType CType;
  95.  
  96.   static size_t get_size(const CType* array)
  97.     { return (array) ? Glib::Container_Helpers::compute_array_size(array) : 0; }
  98.  
  99.   static const CType* get_data(const CType* array, size_t)
  100.     { return array; }
  101.  
  102.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_NONE;
  103. };
  104.  
  105. template <class Tr, class Cont>
  106. struct ArraySourceTraits<Tr,const Cont*> : ArraySourceTraits<Tr,Cont*>
  107. {};
  108.  
  109. /* Convert from a 0-terminated array.  The Cont argument must be a pointer
  110.  * to the first element.  Note that only arrays of the C type are supported.
  111.  * For consistency, the array must be 0-terminated, even though the array
  112.  * size is known at compile time.
  113.  */
  114. template <class Tr, class Cont, size_t N>
  115. struct ArraySourceTraits<Tr,Cont[N]>
  116. {
  117.   typedef typename Tr::CType CType;
  118.  
  119.   static size_t get_size(const CType*)
  120.     { return (N - 1); }
  121.  
  122.   static const CType* get_data(const CType* array, size_t)
  123.     { return array; }
  124.  
  125.   static const Glib::OwnershipType initial_ownership = Glib::OWNERSHIP_NONE;
  126. };
  127.  
  128. template <class Tr, class Cont, size_t N>
  129. struct ArraySourceTraits<Tr,const Cont[N]> : ArraySourceTraits<Tr,Cont[N]>
  130. {};
  131.  
  132. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  133.  
  134.  
  135. /**
  136.  * @ingroup ContHelpers
  137.  */
  138. template <class Tr>
  139. class ArrayHandleIterator
  140. {
  141. public:
  142.   typedef typename Tr::CppType              CppType;
  143.   typedef typename Tr::CType                CType;
  144.  
  145.   typedef std::random_access_iterator_tag   iterator_category;
  146.   typedef CppType                           value_type;
  147.   typedef ptrdiff_t                         difference_type;
  148.   typedef value_type                        reference;
  149.   typedef void                              pointer;
  150.  
  151.   explicit inline ArrayHandleIterator(const CType* pos);
  152.  
  153.   inline value_type operator*() const;
  154.   inline value_type operator[](difference_type offset) const;
  155.  
  156.   inline ArrayHandleIterator<Tr> &     operator++();
  157.   inline const ArrayHandleIterator<Tr> operator++(int);
  158.  
  159.   // All this random access stuff is only there because STL algorithms
  160.   // usually have optimized specializations for random access iterators,
  161.   // and we don't want to give away efficiency for nothing.
  162.   //
  163.   inline ArrayHandleIterator<Tr> &     operator+=(difference_type rhs);
  164.   inline ArrayHandleIterator<Tr> &     operator-=(difference_type rhs);
  165.   inline const ArrayHandleIterator<Tr> operator+ (difference_type rhs) const;
  166.   inline const ArrayHandleIterator<Tr> operator- (difference_type rhs) const;
  167.   inline difference_type operator-(const ArrayHandleIterator<Tr>& rhs) const;
  168.  
  169.   inline bool operator==(const ArrayHandleIterator<Tr>& rhs) const;
  170.   inline bool operator!=(const ArrayHandleIterator<Tr>& rhs) const;
  171.   inline bool operator< (const ArrayHandleIterator<Tr>& rhs) const;
  172.   inline bool operator> (const ArrayHandleIterator<Tr>& rhs) const;
  173.   inline bool operator<=(const ArrayHandleIterator<Tr>& rhs) const;
  174.   inline bool operator>=(const ArrayHandleIterator<Tr>& rhs) const;
  175.  
  176. private:
  177.   const CType* pos_;
  178. };
  179.  
  180. } // namespace Container_Helpers
  181.  
  182.  
  183. /** If a method takes this as an argument, or has this as a return type, then you can use a standard
  184.  * container such as std::list or std::vector.
  185.  * @ingroup ContHandles
  186.  */
  187. template < class T, class Tr = Glib::Container_Helpers::TypeTraits<T> >
  188. class ArrayHandle
  189. {
  190. public:
  191.   typedef typename Tr::CppType  CppType;
  192.   typedef typename Tr::CType    CType;
  193.  
  194.   typedef CppType               value_type;
  195.   typedef size_t                size_type;
  196.   typedef ptrdiff_t             difference_type;
  197.  
  198.   typedef Glib::Container_Helpers::ArrayHandleIterator<Tr>   const_iterator;
  199.   typedef Glib::Container_Helpers::ArrayHandleIterator<Tr>   iterator;
  200.  
  201.   template <class Cont> inline
  202.     ArrayHandle(const Cont& container);
  203.  
  204.   // Take over ownership of an array created by GTK+ functions.
  205.   inline ArrayHandle(const CType* array, size_t array_size, Glib::OwnershipType ownership);
  206.   inline ArrayHandle(const CType* array, Glib::OwnershipType ownership);
  207.  
  208.   // Copying clears the ownership flag of the source handle.
  209.   inline ArrayHandle(const ArrayHandle<T,Tr>& other);
  210.  
  211.   ~ArrayHandle();
  212.  
  213.   inline const_iterator begin() const;
  214.   inline const_iterator end()   const;
  215.  
  216.   template <class U> inline operator std::vector<U>() const;
  217.   template <class U> inline operator std::deque<U>()  const;
  218.   template <class U> inline operator std::list<U>()   const;
  219.  
  220.   template <class Cont> inline
  221.     void assign_to(Cont& container) const;
  222.  
  223.   template <class Out> inline
  224.     void copy(Out pdest) const;
  225.  
  226.   inline const CType* data()  const;
  227.   inline size_t       size()  const;
  228.   inline bool         empty() const;
  229.  
  230. private:
  231.   size_t                      size_;
  232.   const CType*                parray_;
  233.   mutable Glib::OwnershipType ownership_;
  234.  
  235.   // No copy assignment.
  236.   ArrayHandle<T, Tr>& operator=(const ArrayHandle<T,Tr>&);
  237. };
  238.  
  239. /** If a method takes this as an argument, or has this as a return type, then you can use a standard
  240.  * container such as std::list<Glib::ustring> or std::vector<Glib::ustring>.
  241.  * @ingroup ContHandles
  242.  */
  243. typedef ArrayHandle<Glib::ustring> StringArrayHandle;
  244.  
  245.  
  246. /***************************************************************************/
  247. /*  Inline implementation                                                  */
  248. /***************************************************************************/
  249.  
  250. #ifndef DOXYGEN_SHOULD_SKIP_THIS
  251.  
  252. namespace Container_Helpers
  253. {
  254.  
  255. /**** Glib::Container_Helpers::ArrayHandleIterator<> ***********************/
  256.  
  257. template <class Tr> inline
  258. ArrayHandleIterator<Tr>::ArrayHandleIterator(const CType* pos)
  259. :
  260.   pos_ (pos)
  261. {}
  262.  
  263. template <class Tr> inline
  264. typename ArrayHandleIterator<Tr>::value_type ArrayHandleIterator<Tr>::operator*() const
  265. {
  266.   return Tr::to_cpp_type(*pos_);
  267. }
  268.  
  269. template <class Tr> inline
  270. typename ArrayHandleIterator<Tr>::value_type
  271. ArrayHandleIterator<Tr>::operator[](difference_type offset) const
  272. {
  273.   return Tr::to_cpp_type(pos_[offset]);
  274. }
  275.  
  276. template <class Tr> inline
  277. ArrayHandleIterator<Tr>& ArrayHandleIterator<Tr>::operator++()
  278. {
  279.   ++pos_;
  280.   return *this;
  281. }
  282.  
  283. template <class Tr> inline
  284. const ArrayHandleIterator<Tr> ArrayHandleIterator<Tr>::operator++(int)
  285. {
  286.   return ArrayHandleIterator<Tr>(pos_++);
  287. }
  288.  
  289. template <class Tr> inline
  290. ArrayHandleIterator<Tr>&
  291. ArrayHandleIterator<Tr>::operator+=(typename ArrayHandleIterator<Tr>::difference_type rhs)
  292. {
  293.   pos_ += rhs;
  294.   return *this;
  295. }
  296.  
  297. template <class Tr> inline
  298. ArrayHandleIterator<Tr>&
  299. ArrayHandleIterator<Tr>::operator-=(typename ArrayHandleIterator<Tr>::difference_type rhs)
  300. {
  301.   pos_ -= rhs;
  302.   return *this;
  303. }
  304.  
  305. template <class Tr> inline
  306. const ArrayHandleIterator<Tr>
  307. ArrayHandleIterator<Tr>::operator+(typename ArrayHandleIterator<Tr>::difference_type rhs) const
  308. {
  309.   return ArrayHandleIterator<Tr>(pos_ + rhs);
  310. }
  311.  
  312. template <class Tr> inline
  313. const ArrayHandleIterator<Tr>
  314. ArrayHandleIterator<Tr>::operator-(typename ArrayHandleIterator<Tr>::difference_type rhs) const
  315. {
  316.   return ArrayHandleIterator<Tr>(pos_ - rhs);
  317. }
  318.  
  319. template <class Tr> inline
  320. typename ArrayHandleIterator<Tr>::difference_type
  321. ArrayHandleIterator<Tr>::operator-(const ArrayHandleIterator<Tr>& rhs) const
  322. {
  323.   return (pos_ - rhs.pos_);
  324. }
  325.  
  326. template <class Tr> inline
  327. bool ArrayHandleIterator<Tr>::operator==(const ArrayHandleIterator<Tr>& rhs) const
  328. {
  329.   return (pos_ == rhs.pos_);
  330. }
  331.  
  332. template <class Tr> inline
  333. bool ArrayHandleIterator<Tr>::operator!=(const ArrayHandleIterator<Tr>& rhs) const
  334. {
  335.   return (pos_ != rhs.pos_);
  336. }
  337.  
  338. template <class Tr> inline
  339. bool ArrayHandleIterator<Tr>::operator<(const ArrayHandleIterator<Tr>& rhs) const
  340. {
  341.   return (pos_ < rhs.pos_);
  342. }
  343.  
  344. template <class Tr> inline
  345. bool ArrayHandleIterator<Tr>::operator>(const ArrayHandleIterator<Tr>& rhs) const
  346. {
  347.   return (pos_ > rhs.pos_);
  348. }
  349.  
  350. template <class Tr> inline
  351. bool ArrayHandleIterator<Tr>::operator<=(const ArrayHandleIterator<Tr>& rhs) const
  352. {
  353.   return (pos_ <= rhs.pos_);
  354. }
  355.  
  356. template <class Tr> inline
  357. bool ArrayHandleIterator<Tr>::operator>=(const ArrayHandleIterator<Tr>& rhs) const
  358. {
  359.   return (pos_ >= rhs.pos_);
  360. }
  361.  
  362. } // namespace Container_Helpers
  363.  
  364.  
  365. /**** Glib::ArrayHandle<> **************************************************/
  366.  
  367. template <class T, class Tr>
  368.   template <class Cont>
  369. inline
  370. ArrayHandle<T,Tr>::ArrayHandle(const Cont& container)
  371. :
  372.   size_      (Glib::Container_Helpers::ArraySourceTraits<Tr,Cont>::get_size(container)),
  373.   parray_    (Glib::Container_Helpers::ArraySourceTraits<Tr,Cont>::get_data(container, size_)),
  374.   ownership_ (Glib::Container_Helpers::ArraySourceTraits<Tr,Cont>::initial_ownership)
  375. {}
  376.  
  377. template <class T, class Tr> inline
  378. ArrayHandle<T,Tr>::ArrayHandle(const typename ArrayHandle<T,Tr>::CType* array, size_t array_size,
  379.                                Glib::OwnershipType ownership)
  380. :
  381.   size_      (array_size),
  382.   parray_    (array),
  383.   ownership_ (ownership)
  384. {}
  385.  
  386. template <class T, class Tr> inline
  387. ArrayHandle<T,Tr>::ArrayHandle(const typename ArrayHandle<T,Tr>::CType* array,
  388.                                Glib::OwnershipType ownership)
  389. :
  390.   size_      ((array) ? Glib::Container_Helpers::compute_array_size(array) : 0),
  391.   parray_    (array),
  392.   ownership_ (ownership)
  393. {}
  394.  
  395. template <class T, class Tr> inline
  396. ArrayHandle<T,Tr>::ArrayHandle(const ArrayHandle<T,Tr>& other)
  397. :
  398.   size_      (other.size_),
  399.   parray_    (other.parray_),
  400.   ownership_ (other.ownership_)
  401. {
  402.   other.ownership_ = Glib::OWNERSHIP_NONE;
  403. }
  404.  
  405. template <class T, class Tr>
  406. ArrayHandle<T,Tr>::~ArrayHandle()
  407. {
  408.   if(ownership_ != Glib::OWNERSHIP_NONE)
  409.   {
  410.     if(ownership_ != Glib::OWNERSHIP_SHALLOW)
  411.     {
  412.       // Deep ownership: release each container element.
  413.       const CType *const pend = parray_ + size_;
  414.       for(const CType* p = parray_; p != pend; ++p)
  415.         Tr::release_c_type(*p);
  416.     }
  417.     g_free(const_cast<CType*>(parray_));
  418.   }
  419. }
  420.  
  421. template <class T, class Tr> inline
  422. typename ArrayHandle<T,Tr>::const_iterator ArrayHandle<T,Tr>::begin() const
  423. {
  424.   return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_);
  425. }
  426.  
  427. template <class T, class Tr> inline
  428. typename ArrayHandle<T,Tr>::const_iterator ArrayHandle<T,Tr>::end() const
  429. {
  430.   return Glib::Container_Helpers::ArrayHandleIterator<Tr>(parray_ + size_);
  431. }
  432.  
  433. template <class T, class Tr>
  434.   template <class U>
  435. inline
  436. ArrayHandle<T,Tr>::operator std::vector<U>() const
  437. {
  438. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  439.   return std::vector<U>(this->begin(), this->end());
  440. #else
  441.   std::vector<U> temp;
  442.   temp.reserve(this->size());
  443.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  444.   return temp;
  445. #endif
  446. }
  447.  
  448. template <class T, class Tr>
  449.   template <class U>
  450. inline
  451. ArrayHandle<T,Tr>::operator std::deque<U>() const
  452. {
  453. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  454.   return std::deque<U>(this->begin(), this->end());
  455. #else
  456.   std::deque<U> temp;
  457.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  458.   return temp;
  459. #endif
  460. }
  461.  
  462. template <class T, class Tr>
  463.   template <class U>
  464. inline
  465. ArrayHandle<T,Tr>::operator std::list<U>() const
  466. {
  467. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  468.   return std::list<U>(this->begin(), this->end());
  469. #else
  470.   std::list<U> temp;
  471.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  472.   return temp;
  473. #endif
  474. }
  475.  
  476. template <class T, class Tr>
  477.   template <class Cont>
  478. inline
  479. void ArrayHandle<T,Tr>::assign_to(Cont& container) const
  480. {
  481. #ifdef GLIBMM_HAVE_TEMPLATE_SEQUENCE_CTORS
  482.   container.assign(this->begin(), this->end());
  483. #else
  484.   Cont temp;
  485.   Glib::Container_Helpers::fill_container(temp, this->begin(), this->end());
  486.   container.swap(temp);
  487. #endif
  488. }
  489.  
  490. template <class T, class Tr>
  491.   template <class Out>
  492. inline
  493. void ArrayHandle<T,Tr>::copy(Out pdest) const
  494. {
  495.   std::copy(this->begin(), this->end(), pdest);
  496. }
  497.  
  498. template <class T, class Tr> inline
  499. const typename ArrayHandle<T,Tr>::CType* ArrayHandle<T,Tr>::data() const
  500. {
  501.   return parray_;
  502. }
  503.  
  504. template <class T, class Tr> inline
  505. size_t ArrayHandle<T,Tr>::size() const
  506. {
  507.   return size_;
  508. }
  509.  
  510. template <class T, class Tr> inline
  511. bool ArrayHandle<T,Tr>::empty() const
  512. {
  513.   return (size_ == 0);
  514. }
  515.  
  516. #endif /* DOXYGEN_SHOULD_SKIP_THIS */
  517.  
  518. } // namespace Glib
  519.  
  520.  
  521. #endif /* _GLIBMM_ARRAYHANDLE_H */
  522.  
  523.